﻿Imports Commander_Wars.Spieletools
''' <summary>
''' Eine KI mit normalen Faehigkeiten. Unvollstaendig aber Funktionsfaehig.
''' </summary>
''' <remarks></remarks>
Public Class KINormal
    Inherits ObjektKI
    Const AllesBauSumme As Integer = 20000
    Const BilligsterPanzer As Integer = 6000
    Const TeuersterPanzer As Integer = 11000
    Dim Infis As Integer
    Dim TTPs As Integer
    Dim LBoote As Integer
    Dim THelis As Integer
    Dim Spaeher As Integer
    Dim BauModus As BauModi = BauModi.AW2
    Enum BauModi
        InfiFlut
        AW2
        AWDS
    End Enum
    Public Sub New(ByVal neuSpieler As ObjektSpieler)
        MyBase.New(neuSpieler, 1.1#, 1, 0.5#, Besetzungsprioritaeten.MeisteEinheiten, GeldTPAngriffsModus.NurGeld, 10, CSng(1 / 3), 5, 0)
        If Objektverwalter.Spielfeld.Runde > 1 Then
            If Spieler.Einkommen > 10000 Then
                BauModus = BauModi.AWDS
            ElseIf Spieler.Einkommen <= 4000 Or Objektverwalter.Spielfeld.GetSpielgroesse < 400 Then
                BauModus = BauModi.InfiFlut
            Else
                BauModus = BauModi.AW2
            End If
        Else
            BauModus = BauModi.AW2
        End If
    End Sub
    Public Overrides Sub LaunchAI()
        If Objektverwalter.Spielfeld.Runde > 1 Then
            If Spieler.Einkommen > 10000 Then
                BauModus = BauModi.AWDS
            ElseIf Spieler.Einkommen <= 4000 Or Objektverwalter.Spielfeld.GetSpielgroesse < 400 Then
                BauModus = BauModi.InfiFlut
            Else
                BauModus = BauModi.AW2
            End If
        Else
            BauModus = BauModi.AW2
        End If
        MyBase.LaunchAI()
    End Sub

    ''' <summary>
    ''' Fuehrt die Zug bewegungen der Kinderleichten KI aus. Muahaha und dann Boom.Diese KI kann keine Gebaeude bedinnen
    ''' </summary>
    ''' <remarks></remarks>
    Public Overrides Sub KISchleife()
        Objektverwalter.Spielfeld.EingabenErlauben = False
        Schleife = False
        KIModusIntern = KIModiIntern.KIStart
        KIWarten(12)
        While Schleife = False
            MomentaneEinheit = 0
            Select Case KIModusIntern
                Case KIModiIntern.KIStart
                    GabenEinsetzen()
                Case KIModiIntern.StartWarten
                    KIModusIntern = KIModiIntern.GebaeudeAngriff
                Case KIModiIntern.GebaeudeAngriff
                    GebaeudeFeuer()
                Case KIModiIntern.ExternGesteuerteEinheiten
                    ExternGesteurteEinheiten()
                Case KIModiIntern.Besetzen
                    Besetzen()
                Case KIModiIntern.HoelliumZiehen
                    HoelliumZiehen()
                Case KIModiIntern.Fernkampf
                    FernkampfAngriff()
                Case KIModiIntern.Nahkampf
                    NahkampfAngriff()
                Case KIModiIntern.Nahkampfziehen
                    NahkampfZiehen() 'UV
                Case KIModiIntern.Infanterieziehen
                    InfanterieZiehen() 'UV
                Case KIModiIntern.Fernkampfziehen
                    Fernkampfziehen() 'UV
                Case KIModiIntern.Rueckzug
                    Rueckzug() 'UV
                Case KIModiIntern.Ration
                    Ration() 'UV
                Case KIModiIntern.TransporterVerladen
                    EinheitenVerladen()
                    KIModusIntern = KIModiIntern.Transproterziehen
                Case KIModiIntern.Transproterziehen
                    TransporterZiehen(EinheitenSortierKriterien.GroessterBewegungsradius)
                    KIModusIntern = KIModiIntern.Bauen
                Case KIModiIntern.Bauen
                    TruppenWegZiehen()
                    GetAllBuildings()
                    Bauen() 'UV
                Case KIModiIntern.RundenEndeGabeEinsetzen
                    GabenEinsetzen()
                Case KIModiIntern.RundenEnde
                    RundenEnde()
            End Select
        End While
    End Sub
    ''' <summary>
    ''' So werden zu beginn Gaben einer einfachen KI eingesetzt.
    ''' Es wird nicht ueberprueft ob der Einsatz der Gabe bzw. Spezialgabe sinnvoll ist.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub GabenEinsetzen()
        Dim GabeEingesetzt As Boolean = False
        If Spieler.VeraenderteWerte.Gabeeinsatz = True Then
            Dim GabefuellstandKO1 As Integer = Spieler.KOS(0).Gabeleiste
            Dim GabefuellstandKO2 As Integer = -1
            If IsNothing(Spieler.KOS(1)) = False Then
                GabefuellstandKO2 = Spieler.KOS(1).Gabeleiste
            End If
            If GabefuellstandKO1 > Spieler.KOS(0).Gabekosten * Spieler.KOS(0).Sternkosten + Spieler.KOS(0).Sternkosten / 2 Then
                If GabefuellstandKO1 >= (Spieler.KOS(0).Gabekosten + Spieler.KOS(0).SpezialgabeKosten) * Spieler.KOS(0).Sternkosten Then
                    If IsNothing(Spieler.KOS(1)) = False And Objektverwalter.Spielfeld.Regeln.DoppelGabe Then
                        If GabefuellstandKO2 >= (Spieler.KOS(1).SpezialgabeKosten + Spieler.KOS(1).Gabekosten) * Spieler.KOS(1).Sternkosten Then
                            If Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.Beides Then
                            ElseIf Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenAnfang Then
                            ElseIf Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                                Spieler.KOS(0).Doppelgabe()
                                GabeEingesetzt = True
                            ElseIf Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenAnfang And KIModusIntern = KIModiIntern.KIStart Then
                                'Die Doppelgabe kommt euer untergang ist nah Muahaha
                                Spieler.KOS(0).Doppelgabe()
                                GabeEingesetzt = True
                            ElseIf Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.Beides Then
                                Spieler.KOS(0).Doppelgabe()
                                GabeEingesetzt = True
                            End If
                        ElseIf GabefuellstandKO2 <= (Spieler.KOS(1).SpezialgabeKosten + Spieler.KOS(1).Gabekosten) * Spieler.KOS(1).Sternkosten - Spieler.KOS(1).Sternkosten * 3 Then
                            Select Case Spieler.KOS(0).GabeEinsatzstelle
                                Case ObjektKO.KIGabeEinsatzstellen.RundenAnfang
                                    If KIModusIntern = KIModiIntern.KIStart Then
                                        'Die KI setzt die Spezialgabe ein
                                        If Spieler.KOS(0).KannSpezialGabe Then
                                            Spieler.KOS(0).Spezialgabe()
                                            GabeEingesetzt = True
                                        End If
                                    End If
                                Case ObjektKO.KIGabeEinsatzstellen.RundenEnde
                                    If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                                        'Die KI setzt die Spezialgabe ein
                                        If Spieler.KOS(0).KannSpezialGabe Then
                                            Spieler.KOS(0).Spezialgabe()
                                            GabeEingesetzt = True
                                        End If
                                    End If
                                Case ObjektKO.KIGabeEinsatzstellen.Beides
                                    'Die KI setzt die Spezialgabe ein
                                    If Spieler.KOS(0).KannSpezialGabe Then
                                        Spieler.KOS(0).Spezialgabe()
                                        GabeEingesetzt = True
                                    End If
                            End Select
                        End If
                    Else
                        Select Case Spieler.KOS(0).GabeEinsatzstelle
                            Case ObjektKO.KIGabeEinsatzstellen.RundenAnfang
                                If KIModusIntern = KIModiIntern.KIStart Then
                                    'Die KI setzt die Spezialgabe ein
                                    If Spieler.KOS(0).KannSpezialGabe Then
                                        Spieler.KOS(0).Spezialgabe()
                                        GabeEingesetzt = True
                                    End If
                                End If
                            Case ObjektKO.KIGabeEinsatzstellen.RundenEnde
                                If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                                    'Die KI setzt die Spezialgabe ein
                                    If Spieler.KOS(0).KannSpezialGabe Then
                                        Spieler.KOS(0).Spezialgabe()
                                        GabeEingesetzt = True
                                    End If
                                End If
                            Case ObjektKO.KIGabeEinsatzstellen.Beides
                                'Die KI setzt die Spezialgabe ein
                                If Spieler.KOS(0).KannSpezialGabe Then
                                    Spieler.KOS(0).Spezialgabe()
                                    GabeEingesetzt = True
                                End If
                        End Select
                    End If
                End If
            ElseIf GabefuellstandKO1 > Spieler.KOS(0).Gabekosten * Spieler.KOS(0).Sternkosten Then
                If Spieler.KOS(0).UseCOP Then
                    Select Case Spieler.KOS(0).GabeEinsatzstelle
                        Case ObjektKO.KIGabeEinsatzstellen.RundenAnfang
                            If KIModusIntern = KIModiIntern.KIStart Then
                                'Die KI setzt die Spezialgabe ein
                                If Spieler.KOS(0).KannGabe Then
                                    Spieler.KOS(0).Gabe()
                                    GabeEingesetzt = True
                                End If
                            End If
                        Case ObjektKO.KIGabeEinsatzstellen.RundenEnde
                            If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                                'Die KI setzt die Spezialgabe ein
                                If Spieler.KOS(0).KannGabe Then
                                    Spieler.KOS(0).Gabe()
                                    GabeEingesetzt = True
                                End If
                            End If
                        Case ObjektKO.KIGabeEinsatzstellen.Beides
                            'Die KI setzt die Spezialgabe ein
                            If Spieler.KOS(0).KannGabe Then
                                Spieler.KOS(0).Gabe()
                                GabeEingesetzt = True
                            End If
                    End Select
                End If
                End If
        End If
        If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen And GabeEingesetzt = True Then
            MomentaneEinheit = 0
            KIModusIntern = KIModiIntern.GebaeudeAngriff
            'Sonst macht die KI Runden Ende LOL
            KIWarten(2)
            If Schlachtfeld = ObjektSpielfeld.Luftschlacht Then
                Schlachtwechsel(EinheitenSortierKriterien.GroessterBewegungsradius)
            Else
                GetAllUnits(EinheitenSortierKriterien.GroessterBewegungsradius)
            End If
        ElseIf KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
            KIModusIntern = KIModiIntern.RundenEnde
        Else
            KIModusIntern = KIModiIntern.StartWarten
            KIWarten(8)
        End If
    End Sub
    ''' <summary>
    ''' Laesst die Gebaeude feuern
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub GebaeudeFeuer()
        Dim NewUnits As Boolean = False
        While MomentaneEinheit < Gebaeude.Length
            Dim MomGebaeude As ObjektGebaeude = Gebaeude(MomentaneEinheit)
            If Not MomGebaeude.GetRealGebaeudeID = "VERWEIS" Then
                If MomGebaeude.Feuerbereit = 0 Then
                    If TypeOf MomGebaeude Is GebaeudeLaser Then
                        GebaeudeAuswaehlen(KIModiExtern.Schuss, MomGebaeude, New EinheitAmphibienpanzer(0, 1, 1, False), 4)
                    ElseIf TypeOf MomGebaeude Is GebaeudeAruura Then
                        GebaeudeAuswaehlen(KIModiExtern.Schuss, MomGebaeude, New EinheitAmphibienpanzer(0, 1, 1, False), 4)
                    ElseIf TypeOf MomGebaeude Is GebaeudeOmega_Rakete Then
                        Dim Omega As GebaeudeOmega_Rakete = MomGebaeude
                        If Omega.RaketeFeuerbereit = True Then
                            Dim Ziel As Point = GetBestenEinschlagsOrt(Omega.Reichweite, Omega.Schaden)
                            If Ziel.X >= 0 Then
                                GebaeudeAuswaehlen(KIModiExtern.OmegaRaketeStarten, Omega, New EinheitArtillerie(0, Ziel.X, Ziel.Y), 4)
                            End If
                        ElseIf Spieler.Fonds > 30000 Then
                            For I = 0 To Omega.Variablen.Length - 1
                                If Omega.Variablen(I).Wert = 1 Then
                                    'Wir bauen einen Teil der Omega-Rakete
                                    GebaeudeAuswaehlen(KIModiExtern.OmegaUpgradeKaufen, Omega, New EinheitArtillerie(0, I, 0), 4)
                                    Exit For
                                End If
                            Next
                        End If
                    Else
                        Dim Ziel As Point = GetBestesGebaeudeFeuer(MomGebaeude)
                        If Ziel.X >= 0 And Ziel.Y >= 0 Then
                            If MomGebaeude.Angriff = ObjektGebaeude.Angriffe.SchussN Or MomGebaeude.Angriff = ObjektGebaeude.Angriffe.SchussW Or MomGebaeude.Angriff = ObjektGebaeude.Angriffe.SchussS Or MomGebaeude.Angriff = ObjektGebaeude.Angriffe.SchussO Then
                                GebaeudeAuswaehlen(KIModiExtern.Schuss, MomGebaeude, Objektverwalter.Spielfeld.Einheiten(Ziel.X, Ziel.Y, Schlachtfeld), 4)
                            Else
                                'Wir muessen erst noch eine virtuelle Einheit erschaffen.=)
                                GebaeudeAuswaehlen(KIModiExtern.Schuss, MomGebaeude, New EinheitAmphibienpanzer(0, Ziel.X, Ziel.Y, False), 4)
                            End If
                        End If
                    End If
                ElseIf MomGebaeude.GebaeudeID = "FABRIK" Then
                    Dim BauEinheiten As String() = BestesGeldAusgebenBeiFabrik(MomGebaeude)
                    Dim Y As Integer = MomGebaeude.Rechteck.Y + 2
                    Dim X As Integer = MomGebaeude.Rechteck.X - 1
                    For I = 0 To BauEinheiten.Length - 1
                        If Not BauEinheiten(I) = "" Then
                            GebaeudeAuswaehlen(KIModiExtern.FabrikBauen, MomGebaeude, ObjektLadeklasse.NewEinheit(BauEinheiten(I), Spieler.Spieler, X, Y), 4)
                            NewUnits = True
                        End If
                        X += 1
                    Next
                End If
            End If
            MomentaneEinheit += 1
        End While
        If NewUnits Or Einheiten.Length = 0 Then
            GetAllUnits(EinheitenSortierKriterien.GroessterBewegungsradius)
        End If
        KIModusIntern = KIModiIntern.ExternGesteuerteEinheiten
    End Sub
    ''' <summary>
    ''' Mit dieser Funktion Suchen sich die Einfachen KI's die Gebaeude aus die sie besetzen
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Besetzen()
        KOEinheitErschaffen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim Einheit As Integer = MomentaneEinheit
                If Einheiten(Einheit).KannBesetzen = True Then
                    If Einheiten(MomentaneEinheit).HatsichBewegt = False Then
                        Dim WSS As Wegsuchsystem = CreateWSS(Einheiten(Einheit))
                        If Einheiten(Einheit).Besetzen = True Then
                            'Diese Einheit besetzt gerade ein Gebaeude da macht sie damit gleich weiter
                            Einheitauswaehlen(Einheiten(Einheit), New Point(Einheiten(Einheit).X, Einheiten(Einheit).Y), KIModiExtern.Besetzen, Nothing, WSS, 4)
                        ElseIf Einheiten(Einheit).KannBesetzen = True Then
                            Dim G As ObjektGebaeude = Objektverwalter.Spielfeld.Landschaften(Einheiten(Einheit).X, Einheiten(Einheit).Y, Schlachtfeld).Gebaeude
                            If G Is Nothing Then
                                Dim Ziel As Point = GetBauGebaeudeZumBesetzen(Einheiten(Einheit), WSS)
                                If Ziel.X >= 0 Then
                                    'Diese KI sucht noch nicht nach dem Besten Gebaeude sondern besetzt das erst beste
                                    WSS.Ziel(Ziel.X, Ziel.Y, True)
                                    Dim Bes As ObjektGebaeude = Objektverwalter.Spielfeld.Landschaften(Ziel.X, Ziel.Y, Schlachtfeld).Gebaeude
                                    If Bes.Angriff = ObjektGebaeude.Angriffe.Silo Then
                                        Dim Ziel2 As Point = GetBestenEinschlagsOrt(Bes.Reichweite, Bes.Schaden)
                                        Einheitauswaehlen(Einheiten(Einheit), Ziel, KIModiExtern.SiloZuenden, New EinheitAmphibienpanzer(0, Ziel2.X, Ziel2.Y), WSS, 4)
                                    Else
                                        Einheitauswaehlen(Einheiten(Einheit), Ziel, KIModiExtern.Besetzen, Nothing, WSS, 4)
                                    End If
                                End If
                            ElseIf G.IsBesetzung(Spieler.Spieler) = True Then
                                Dim Ziel As New Point(Einheiten(Einheit).X, Einheiten(Einheit).Y)
                                If G.Angriff = ObjektGebaeude.Angriffe.Silo Then
                                    Dim Ziel2 As Point = GetBestenEinschlagsOrt(G.Reichweite, G.Schaden)
                                    Einheitauswaehlen(Einheiten(Einheit), Ziel, KIModiExtern.SiloZuenden, New EinheitAmphibienpanzer(0, Ziel2.X, Ziel2.Y), WSS, 4)
                                Else
                                    Einheitauswaehlen(Einheiten(Einheit), Ziel, KIModiExtern.Besetzen, Nothing, WSS, 4)
                                End If
                            Else
                                Dim Ziel As Point = GetBauGebaeudeZumBesetzen(Einheiten(Einheit), WSS)
                                If Ziel.X >= 0 Then
                                    'Diese KI sucht noch nicht nach dem Besten Gebaeude sondern besetzt das erst beste
                                    WSS.Ziel(Ziel.X, Ziel.Y, True)
                                    Dim Bes As ObjektGebaeude = Objektverwalter.Spielfeld.Landschaften(Ziel.X, Ziel.Y, Schlachtfeld).Gebaeude
                                    If Bes.Angriff = ObjektGebaeude.Angriffe.Silo Then
                                        Dim Ziel2 As Point = GetBestenEinschlagsOrt(Bes.Reichweite, Bes.Schaden)
                                        Einheitauswaehlen(Einheiten(Einheit), Ziel, KIModiExtern.SiloZuenden, New EinheitAmphibienpanzer(0, Ziel2.X, Ziel2.Y), WSS, 4)
                                    Else
                                        Einheitauswaehlen(Einheiten(Einheit), Ziel, KIModiExtern.Besetzen, Nothing, WSS, 4)
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.HoelliumZiehen
    End Sub
    ''' <summary>
    ''' Zieht die Hoelliums des Spielers
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub HoelliumZiehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                If Einheiten(MomentaneEinheit).HatsichBewegt = False Then
                    If Einheiten(MomentaneEinheit).EinheitenID = MovementSorts.HOELLIUM.tostring.toupper Then
                        'Wir haben ein Hoellium zum ziehen.=)
                        Dim Hoellium As ObjektEinheit = Einheiten(MomentaneEinheit)
                        Dim WSS As New Wegsuchsystem(Hoellium, Hoellium.X, Hoellium.Y, Hoellium.GetMap, -1)
                        Dim Ziel As Point = GetNaehestesHoelliumZiel(Hoellium, WSS)
                        If Ziel.X >= 0 Then
                            Einheitauswaehlen(Hoellium, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Fernkampf
    End Sub
    ''' <summary>
    ''' Fuehrt die Fernkaempfe der einfachen KI aus.
    ''' Diese KI haut mit ihren Fernwaffen in keinem Fall ab.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub FernkampfAngriff()
        Dim M As ObjektSpielMenue = Objektverwalter.Menue
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.HatsichBewegt = False Then
                    If E.MaximaleReichweite > 1 Then
                        Dim WSS As Wegsuchsystem = CreateWSS(E)
                        'OH je  das wird noch komplikate
                        If E.CanIndirectMoveAndFire And Spieler.KOS(0).FireandMove = True Then
                            Dim Feld As Point = GetBestesFernkampfOpferFirstFernwaffen(E, GetAllFernKampfFelderGebaeude(E, E.X, E.Y, True))
                            If Feld.X >= 0 Then
                                Einheitauswaehlen(E, New Point(E.X, E.Y), KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Feld.X, Feld.Y, Schlachtfeld), WSS)
                                Dim Felder As Point2 = GetBestesFernkampfOpferMitBewegung(E, WSS)
                                If Felder.Point1.X >= 0 And Felder.Point2.X >= 0 Then
                                    'So wir haben ein Opfer.
                                    NaechsterBefehl(Felder.Point1, Objektverwalter.Spielfeld.Einheiten(Felder.Point2.X, Felder.Point2.Y, Schlachtfeld), KIModiExtern.Angriff, WSS, 4)
                                End If
                            Else
                                Dim Felder As Point2 = GetBestesFernkampfFeldmitBewegung(E, WSS)
                                If Felder.Point1.X >= 0 And Felder.Point2.X >= 0 Then
                                    'So wir haben ein Opfer.
                                    Einheitauswaehlen(E, Felder.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Felder.Point2.X, Felder.Point2.Y, Schlachtfeld), WSS)
                                End If
                            End If
                            EinheitAbwaehlen()
                        ElseIf E.CanIndirectMoveAndFire Then
                            'Ein Angriff ziehen und Feuern wie beim Nahkampf
                            Dim Felder As Point2 = GetBestesFernkampfOpferMitBewegung(E, WSS)
                            If Felder.Point1.X >= 0 And Felder.Point2.X >= 0 Then
                                'So wir haben ein Opfer.
                                Einheitauswaehlen(E, Felder.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Felder.Point2.X, Felder.Point2.Y, Schlachtfeld), WSS)
                            End If
                        ElseIf Spieler.KOS(0).FireandMove = True Then
                            'Wir suchen uns ein Opfer
                            Dim Feld As Point = GetBestesFernkampfOpferFirstFernwaffen(E, GetAllFernKampfFelderGebaeude(E, E.X, E.Y, True))
                            If Feld.X >= 0 Then
                                Einheitauswaehlen(E, New Point(E.X, E.Y), KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Feld.X, Feld.Y, Schlachtfeld), WSS)
                            End If
                            'wir haben unser Opfer angegriffen jetzt sollten wir die Einheit noch ziehen.
                            WSS = New Wegsuchsystem(E, E.X, E.Y, Einheiten(MomentaneEinheit).GetMap, -1)
                            Dim Ziel As Point = GetNaehestesFernkampffeldSicher(E, WSS)
                            If Ziel.X >= 0 Then
                                If Objektverwalter.Spielfeld.AktuelleEinheit Is Nothing Then
                                    Einheitauswaehlen(E, New Point(E.X, E.Y), KIModiExtern.Warten, Nothing, WSS)
                                Else
                                    NaechsterBefehl(Ziel, Nothing, KIModiExtern.Warten, WSS, 4)
                                End If
                            Else
                                EinheitAbwaehlen()
                            End If
                        Else
                            'Das ist mir die liebste und einfachst Situation Uff.
                            Dim Feld As Point = GetBestesFernkampfOpferFirstFernwaffen(E, GetAllFernKampfFelderGebaeude(E, E.X, E.Y, True))
                            If Feld.X >= 0 Then
                                Dim Opfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Feld.X, Feld.Y, Schlachtfeld)
                                If Opfer Is Nothing Then Opfer = ObjektLadeklasse.NewEinheit("ABPZ", 0, Feld.X, Feld.Y, 100, False)
                                Einheitauswaehlen(E, New Point(E.X, E.Y), KIModiExtern.Angriff, Opfer, WSS, 4)
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Nahkampf
    End Sub
    ''' <summary>
    ''' So ziehen einfache KI's in den Nahkampf
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub NahkampfAngriff()
        While MomentaneEinheit < Einheiten.Length
            Dim Einheit As ObjektEinheit = Einheiten(MomentaneEinheit)
            If ExistUnit(Einheit) = True Then
                If Einheit.IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If Einheit.KannBesetzen = False Then
                        If Einheit.MinimaleReichweite = 1 Or Not Einheit.Waffe1 = "Keine" Then
                            Dim WSS As Wegsuchsystem = CreateWSS(Einheit)
                            Dim Feld As Point2 = GetBestesNahkampfOpferFeldSicher(Einheit, WSS, GetAllNahKampffelder(Einheit, True, WSS))
                            If Feld.Point1.X >= 0 And Feld.Point2.X >= 0 Then
                                Einheitauswaehlen(Einheit, Feld.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Feld.Point2.X, Feld.Point2.Y, Schlachtfeld), WSS, 4)
                                EinheitGezogenVonVorneStarten()
                                Exit Sub
                            Else
                                Feld = GetBestesNahkampfGebaeude(Einheit, WSS)
                                If Feld.Point1.X >= 0 And Feld.Point2.X >= 0 Then
                                    Einheitauswaehlen(Einheit, Feld.Point1, KIModiExtern.Angriff, New EinheitAmphibienpanzer(0, Feld.Point2.X, Feld.Point2.Y), WSS, 4)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Nahkampfziehen
    End Sub


    ''' <summary>
    ''' So werden die Einheiten  von einfachen KI's zum Ziel gefuehrt
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub NahkampfZiehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If E.MinimaleReichweite = 1 Or Not Einheiten(MomentaneEinheit).Waffe1 = "Keine" Then
                        If E.KannBesetzen = False Then
                            'So das ist vieleicht eine Nahkampfeinheit und zwar kein Infaterist
                            'und diese Einheit kann nicht Angreifen oder doch nah ja das ist ja eine doofe KI
                            'Also keine Abfrage!
                            Dim WSS As New Wegsuchsystem(E, E.X, E.Y, E.GetMap, -1, , )
                            Dim Ziel As Point = GetNaehestenNahkampfFeind(E, WSS)

                            If Ziel.X >= 0 Then
                                Ziel = CalculateRealZiel(WSS, Ziel, E, New Point)
                                If E.KannTarnen Then
                                    If E.GetTarnung() Then
                                        Einheitauswaehlen(E, Ziel, KIModiExtern.Auftauchen, Nothing, WSS, 4)
                                        EinheitGezogenVonVorneStarten()
                                        Exit Sub
                                    Else
                                        Einheitauswaehlen(E, Ziel, KIModiExtern.Tarnen, Nothing, WSS, 4)
                                        EinheitGezogenVonVorneStarten()
                                        Exit Sub
                                    End If
                                Else
                                    Einheitauswaehlen(E, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                End If
                            Else
                                Ziel = ZumNaehestenHQZiehen(Einheiten(MomentaneEinheit), WSS)
                                If Ziel.X > 0 Then
                                    Einheitauswaehlen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Infanterieziehen
    End Sub
    ''' <summary>
    ''' So ziehen die Infanteristen
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub InfanterieZiehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                If Einheiten(MomentaneEinheit).IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If Einheiten(MomentaneEinheit).KannBesetzen Then
                        Dim WSS As Wegsuchsystem = Nothing
                        Dim Ziel As Point2 = GetBestesNahkampfOpfer(Einheiten(MomentaneEinheit), WSS)
                        If Ziel.Point1.X >= 0 And Ziel.Point2.X >= 0 Then
                            Einheitauswaehlen(Einheiten(MomentaneEinheit), Ziel.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Ziel.Point2.X, Ziel.Point2.Y, Schlachtfeld), WSS, 4)
                            EinheitGezogenVonVorneStarten()
                            Exit Sub
                        Else
                            'wir schauen ob wir zu einer Besetzung gehen
                            If InfantrieMoveToTransporterOrBesetzung(Einheiten(MomentaneEinheit)) Then
                                Exit Sub
                            ElseIf Not Einheiten(MomentaneEinheit).Waffe1 = "Keine" Or Einheiten(MomentaneEinheit).MinimaleReichweite = 1 Then
                                WSS = New Wegsuchsystem(Einheiten(MomentaneEinheit), , True)
                                'Wir gehen zu einem Feind.
                                Dim Zielpunkt As Point = GetNaehestenNahkampfFeind(Einheiten(MomentaneEinheit), WSS)
                                If Zielpunkt.X >= 0 Then
                                    Einheitauswaehlen(Einheiten(MomentaneEinheit), Zielpunkt, KIModiExtern.Warten, Nothing, WSS)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                Else
                                    Zielpunkt = ZumNaehestenHQZiehen(Einheiten(MomentaneEinheit), WSS)
                                    If Zielpunkt.X > 0 Then
                                        Einheitauswaehlen(Einheiten(MomentaneEinheit), Zielpunkt, KIModiExtern.Warten, Nothing, WSS, 4)
                                        EinheitGezogenVonVorneStarten()
                                        Exit Sub
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Fernkampfziehen
    End Sub
    ''' <summary>
    ''' So werden die Fernkampf Einheiten der Kinderleichten KI gezogen
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Fernkampfziehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                If Einheiten(MomentaneEinheit).IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If Einheiten(MomentaneEinheit).MaximaleReichweite > 1 Then
                        If Einheiten(MomentaneEinheit).KannBesetzen = False Then
                            Dim WSS As New Wegsuchsystem(Einheiten(MomentaneEinheit), Einheiten(MomentaneEinheit).X, Einheiten(MomentaneEinheit).Y, Einheiten(MomentaneEinheit).GetMap, -1)
                            Dim Ziel As Point = GetNaehestesFernkampffeldSicher(Einheiten(MomentaneEinheit), WSS)
                            If Ziel.X >= 0 Then
                                Einheitauswaehlen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                EinheitGezogenVonVorneStarten()
                                Exit Sub
                            Else
                                Ziel = ZumNaehestenHQZiehen(Einheiten(MomentaneEinheit), WSS)
                                If Ziel.X > 0 Then
                                    Einheitauswaehlen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                Else
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Rueckzug
    End Sub

    Private Sub Rueckzug()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.HatsichBewegt = False Then
                    If E.Treibstoff <> 0 Then
                        If E.IsLowPowerUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) Then
                            Dim WSS As New Wegsuchsystem(E, E.X, E.Y, E.GetMap, -1)
                            Dim Ziel As Point = GetNaehestesRationsFeld(E, WSS)
                            If Ziel.X >= 0 Then
                                Einheitauswaehlen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                EinheitGezogenVonVorneStarten()
                                If E.getKP < MinimaleKP Then
                                    If Ziel.X = E.X And E.Y = Ziel.Y Then
                                        'Nun warten wir bis wir geheilt sind.
                                        Spieler.AddExternGezogeneEinheit(E.X, E.Y, E, ObjektSpieler.ExternGezogeneEinheit.Befehle.Heilen, "", ObjektSpieler.ExternGezogeneEinheit.NaechsteBefehle.Entfernen)
                                    End If
                                End If
                                Exit Sub
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        MomentaneEinheit = 0
        KIModusIntern = KIModiIntern.Ration
    End Sub
    Private Sub Ration()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.Faehigkeit = "Ration" Or E.Faehigkeit = "RationSame" Then
                    If E.IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) Then
                        If Not E.HasLadung Then
                            Dim WSS As New Wegsuchsystem(E, E.X, E.Y, E.GetMap, -1)
                            Dim Ziel As Point = GetNaehestesRationsVerteilFeld(E, WSS)
                            If Ziel.X >= 0 Then
                                Einheitauswaehlen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Ration, Nothing, WSS, 4)
                                EinheitGezogenVonVorneStarten()
                                Exit Sub
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        MomentaneEinheit = 0
        KIModusIntern = KIModiIntern.TransporterVerladen
    End Sub




#Region "Einheiten bauen"
    ''' <summary>
    ''' Laesst die KI Truppen bauen.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Bauen()
        TrimGebaeude()
        If Objektverwalter.Spielfeld.Runde = 1 Then
            Gebaeude = SortGebaeude(Gebaeude, GebaeudeSortierKriterien.Zufall)
        Else
            Gebaeude = SortGebaeude(Gebaeude, GebaeudeSortierKriterien.NaehestenZumFeind)
        End If
        If Spieler.Bauprioritaeten IsNot Nothing Then
            KIGenerellerSuperBau.Bauen(Gebaeude, Spieler.Bauprioritaeten)
        Else
            'Wir initialiesiren mal den Baumodus
            Infis = CountInfanteristen() 'Wie viele Infis haben wir?
            TTPs = CountAnyUnit("TTP") 'Wie viele TTPs?
            LBoote = CountAnyUnit("L-BOOT") 'Wie viele LandeBoote?
            THelis = CountAnyUnit("T-HELI") 'Wie viele T-Helis?
            Spaeher = CountAnyUnit("SPAEHER") 'Wie viele Spaeher?
            Dim LBootBau As Boolean = IsLandeBootBauSinnvoll()
            Dim LBootKosten As Integer = Spieler.Teurungsrate("L-BOOT", 0, 0) * ObjektLadeklasse.GetEinheitenkosten("L-BOOT")
            'Je nach Karte bauen wir anderes
            If BauModus = BauModi.AW2 Then
                'Erst mal Zaehlen wir die Zahl von bestimmten Einheiten.
                Dim DurchGaenge As Integer = 0
                If Spieler.VeraenderteWerte.KeinBau = False Then
                    While MomentaneEinheit < Gebaeude.Length
                        Dim BauGebaeude As ObjektGebaeude = Gebaeude(MomentaneEinheit)
                        If Objektverwalter.Spielfeld.Einheiten(BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, Schlachtfeld) Is Nothing Then
                            If BauGebaeude.GetBaulisteThisPlayer.Length > 0 Then
                                If Spieler.Fonds < 20000 Or Objektverwalter.Spielfeld.Runde = 1 Then
                                    'auf dem Feld ist keine Einheit und das Gebaeude kann Einheiten bauen
                                    If Infis < 5 And CanBuildInfi(BauGebaeude) = True Then
                                        'Wir bauen Infanteristen.
                                        InfisBauen(BauGebaeude)
                                    ElseIf TTPs < 1 And Infis >= 5 And BauGebaeude.CanBuildUnit("TTP") Then
                                        'Wir bauen einen TTP
                                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, New EinheitTTP(Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y), 4)
                                        TTPs += 1
                                    ElseIf THelis < 1 And Infis >= 5 And BauGebaeude.CanBuildUnit("T-HELI") Then
                                        'Wir bauen einen T-Heli
                                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, New EinheitTransporthelikopter(Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y), 4)
                                        THelis += 1
                                    ElseIf Infis >= 5 And LBoote < 2 And BauGebaeude.CanBuildUnit("L-BOOT") And LBootBau Then
                                        'Wir baut ein L-Boot
                                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, New EinheitL_Boot(Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y), 4)
                                        LBoote += 1
                                    ElseIf Infis >= 5 And TTPs >= 1 And Spaeher < 1 And BauGebaeude.CanBuildUnit("SPAEHER") Then
                                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, New EinheitSpaeher(Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y), 4)
                                        Spaeher += 1
                                    ElseIf Spieler.Fonds > AllesBauSumme And Objektverwalter.Spielfeld.Runde > 1 Then
                                        CreatePanzerFlugzeuge(BauGebaeude)
                                    ElseIf Infis >= 5 And TTPs >= 1 And THelis >= 1 Then
                                        'Wir bauen Panzer und Flugzeuge und Schiffe.
                                        CreatePanzerFlugzeuge(BauGebaeude)
                                    ElseIf Infis >= 5 And TTPs >= 1 And Spieler.Fonds >= BilligsterPanzer And BauGebaeude.GetBaulisteThisPlayer.Contains("INF") Then
                                        'Wir bauen einen Panzer.
                                        CreatePanzerFlugzeuge(BauGebaeude)
                                    End If
                                Else
                                    CreateTeursteEinheit(BauGebaeude)
                                End If
                            End If
                        End If
                        MomentaneEinheit += 1
                        If MomentaneEinheit >= Gebaeude.Length Then
                            'wir sind alle Gebaeude einmal Durchgegangen evtl. gehen wir sie noch mal durch.
                            If Spieler.Fonds > BilligsterPanzer And DurchGaenge < 10 Then
                                MomentaneEinheit = 0
                                DurchGaenge += 1
                            End If
                        End If
                    End While
                End If
            ElseIf BauModus = BauModi.InfiFlut Then
                Dim DurchGaenge As Integer = 0
                If Spieler.VeraenderteWerte.KeinBau = False Then
                    While MomentaneEinheit < Gebaeude.Length
                        Dim BauGebaeude As ObjektGebaeude = Gebaeude(MomentaneEinheit)
                        If Objektverwalter.Spielfeld.Einheiten(BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, Schlachtfeld) Is Nothing Then
                            If BauGebaeude.GetBaulisteThisPlayer.Length > 0 Then
                                If LBootBau And LBoote < 2 And Spieler.Fonds > 12000 And Infis >= 4 Then
                                    If BauGebaeude.CanBuildUnit("L-BOOT") Then
                                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, New EinheitL_Boot(Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y), 4)
                                        LBoote += 1
                                    End If
                                Else
                                    If CanBuildInfi(BauGebaeude) = True Then
                                        If Spieler.Fonds > 10000 Then
                                            CreatePanzerFlugzeuge(BauGebaeude)
                                        ElseIf Spieler.Fonds > 6000 And Zufallszahl(0, 8) <= 1 And BauGebaeude.CanBuildUnit("ART") Then
                                            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, ObjektLadeklasse.NewEinheit("ART", Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, True), 4)
                                        Else
                                            InfisBauen(BauGebaeude)
                                        End If
                                    ElseIf BauGebaeude.CanBuildUnit("K-HELI") And Spieler.Fonds >= Spieler.Teurungsrate("K-HELI", BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) * ObjektLadeklasse.GetEinheitenkosten("K-HELI") Then
                                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, ObjektLadeklasse.NewEinheit("K-HELI", Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, True), 4)
                                    End If
                                End If
                            End If
                        End If
                        MomentaneEinheit += 1
                        If MomentaneEinheit >= Gebaeude.Length Then
                            'wir sind alle Gebaeude einmal Durchgegangen evtl. gehen wir sie noch mal durch.
                            If Spieler.Fonds > BilligsterPanzer And DurchGaenge < 10 Then
                                MomentaneEinheit = 0
                                DurchGaenge += 1
                            End If
                        End If
                    End While
                End If
            ElseIf BauModus = BauModi.AWDS Then
                Dim FondsNaechsteRunde As Integer = Spieler.Fonds + Spieler.Einkommen
                Dim RKWKosten As Integer = Spieler.Teurungsrate("RKW", 0, 0) * ObjektLadeklasse.GetEinheitenkosten("RKW")

                Dim TeuersteEinheitNaechsteRunde As Integer = -1
                For Each G In Gebaeude
                    If G.GetBaulisteThisPlayer.Length > 0 Then
                        Dim T As Integer = GetTeuersteEinheitenPreis(G, FondsNaechsteRunde)
                        If T > TeuersteEinheitNaechsteRunde Then TeuersteEinheitNaechsteRunde = T
                    End If
                Next
                Dim AusgabeFonds As Integer = 0
                If Spieler.Fonds < AllesBauSumme Then
                    AusgabeFonds = FondsNaechsteRunde - TeuersteEinheitNaechsteRunde
                Else
                    AusgabeFonds = Spieler.Fonds
                End If

                Dim DurchGaenge As Integer = 0
                If Spieler.VeraenderteWerte.KeinBau = False Then
                    While MomentaneEinheit < Gebaeude.Length
                        If AusgabeFonds > Spieler.Fonds Then AusgabeFonds = Spieler.Fonds
                        Dim BauGebaeude As ObjektGebaeude = Gebaeude(MomentaneEinheit)
                        If Objektverwalter.Spielfeld.Einheiten(BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, Schlachtfeld) Is Nothing Then
                            If BauGebaeude.GetBaulisteThisPlayer.Length > 0 Then
                                If LBootBau And LBoote < 2 Then
                                    If BauGebaeude.CanBuildUnit("L-BOOT") Then
                                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, New EinheitL_Boot(Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y), 4)
                                        LBoote += 1
                                        FondsNaechsteRunde = Spieler.Fonds + Spieler.Einkommen
                                    ElseIf Spieler.Fonds < LBootKosten Then
                                        CreatePanzerFlugzeuge(BauGebaeude, AusgabeFonds)
                                        FondsNaechsteRunde = Spieler.Fonds + Spieler.Einkommen
                                        AusgabeFonds = FondsNaechsteRunde - TeuersteEinheitNaechsteRunde
                                    ElseIf DurchGaenge > 0 Then
                                        If Infis < 5 Or Zufallszahl(0, 5) >= 3 Then
                                            InfisBauen(BauGebaeude)
                                        Else
                                            CreatePanzerFlugzeuge(BauGebaeude)
                                        End If
                                        FondsNaechsteRunde = Spieler.Fonds + Spieler.Einkommen
                                    End If
                                Else
                                    If Spieler.Fonds >= RKWKosten Then
                                        CreateTeursteEinheit(BauGebaeude)
                                        'Ein kleines Update
                                        FondsNaechsteRunde = Spieler.Fonds + Spieler.Einkommen
                                    ElseIf AusgabeFonds > 0 Then
                                        If Infis < 5 Or Zufallszahl(0, 5) >= 3 Then
                                            InfisBauen(BauGebaeude, AusgabeFonds)
                                            FondsNaechsteRunde = Spieler.Fonds + Spieler.Einkommen
                                            AusgabeFonds = FondsNaechsteRunde - TeuersteEinheitNaechsteRunde
                                        ElseIf AusgabeFonds < BilligsterPanzer Then
                                            InfisBauen(BauGebaeude, AusgabeFonds)
                                            FondsNaechsteRunde = Spieler.Fonds + Spieler.Einkommen
                                            AusgabeFonds = FondsNaechsteRunde - TeuersteEinheitNaechsteRunde
                                        Else
                                            CreatePanzerFlugzeuge(BauGebaeude, AusgabeFonds)
                                            FondsNaechsteRunde = Spieler.Fonds + Spieler.Einkommen
                                            AusgabeFonds = FondsNaechsteRunde - TeuersteEinheitNaechsteRunde
                                        End If
                                    End If
                                End If
                            End If
                        End If
                        MomentaneEinheit += 1
                        If MomentaneEinheit >= Gebaeude.Length Then
                            'wir sind alle Gebaeude einmal Durchgegangen evtl. gehen wir sie noch mal durch.
                            If AusgabeFonds >= 1000 And DurchGaenge < 10 Then
                                MomentaneEinheit = 0
                                DurchGaenge += 1
                            End If
                        End If
                    End While
                End If
            End If
        End If
        MomentaneEinheit = 0
        If Schlachtfeld = ObjektSpielfeld.Bodenschlacht And Objektverwalter.Spielfeld.Regeln.Luftschlacht = True Then
            Schlachtwechsel(EinheitenSortierKriterien.Zufall)
            KIModusIntern = KIModiIntern.StartWarten
        Else
            'Wir beenden.
            KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen
        End If
    End Sub
    ''' <summary>
    ''' Baut einen Infi Mech oder Scharfschuetzen irgendetwas, das besetzen kann.;)
    ''' </summary>
    ''' <param name="BauGebaeude"></param>
    ''' <remarks></remarks>
    Private Sub InfisBauen(ByVal BauGebaeude As ObjektGebaeude, Optional ByVal Prueffonds As Integer = -1)
        If Prueffonds < 0 Then
            Prueffonds = Spieler.Fonds
        End If
        Dim Infis As String() = GetBuildInfis(BauGebaeude, Prueffonds)
        If Infis.Length > 0 Then
            If CanMoveAfterBuilding(New EinheitInfanterie(0, 0, 0), BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) = True Then
                If Zufallszahl(1, 100) < 70 Then
                    Dim BilligsteTruppe As ObjektEinheit = Nothing
                    For I2 = 0 To Infis.Length - 1
                        Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Infis(I2), Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y)
                        If BilligsteTruppe Is Nothing Then
                            BilligsteTruppe = E
                        ElseIf E.Kosten < BilligsteTruppe.Kosten Then
                            BilligsteTruppe = E
                        ElseIf E.Kosten = BilligsteTruppe.Kosten And Zufallszahl(0, 2) = 0 Then
                            BilligsteTruppe = E
                        End If
                    Next
                    'Dann mal los ihr Infis
                    GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, BilligsteTruppe)
                    Me.Infis += 1
                Else
                    If Spieler.Fonds > 4000 And Objektverwalter.Spielfeld.Runde > 1 Then
                        GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, ObjektLadeklasse.NewEinheit(Infis(Zufallszahl(0, Infis.Length - 1)), Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y))
                        Me.Infis += 1
                    ElseIf Spieler.Fonds > 10000 And Objektverwalter.Spielfeld.Runde = 1 Then
                        If Infis.Length > 1 And Zufallszahl(0, 10) < 8 Then
                            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, ObjektLadeklasse.NewEinheit(Infis(Zufallszahl(1, Infis.Length - 1)), Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y))
                            Me.Infis += 1
                        Else
                            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, ObjektLadeklasse.NewEinheit(Infis(Zufallszahl(0, Infis.Length - 1)), Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y))
                            Me.Infis += 1
                        End If
                    ElseIf BauModus = BauModi.InfiFlut And Objektverwalter.Spielfeld.Runde > 1 Then
                        If Infis.Length > 1 And Zufallszahl(0, 10) < 8 Then
                            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, ObjektLadeklasse.NewEinheit(Infis(Zufallszahl(1, Infis.Length - 1)), Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y))
                            Me.Infis += 1
                        Else
                            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, ObjektLadeklasse.NewEinheit(Infis(Zufallszahl(0, Infis.Length - 1)), Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y))
                            Me.Infis += 1
                        End If
                    Else
                        For I = 0 To Infis.Length - 1
                            If Infis(I) = "INF" Then
                                GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, New EinheitInfanterie(Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y))
                                Me.Infis += 1
                                Exit For
                            End If
                        Next
                    End If
                End If
            End If
        End If
    End Sub
    ''' <summary>
    ''' Laesst diese KI nach einem gewissen System einen Panzer bzw. Flugzeug bauen.
    ''' </summary>
    ''' <param name="BauGebaeude"></param>
    ''' <remarks></remarks>
    Private Sub CreatePanzerFlugzeuge(ByVal BauGebaeude As ObjektGebaeude)
        Dim Bauliste As New Stack(Of ObjektEinheit)
        If Spieler.Fonds > AllesBauSumme Then
            For Each Einheit In BauGebaeude.GetBaulisteThisPlayer
                If BauGebaeude.CanBuildUnit(Einheit) Then
                    Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Einheit, Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, )
                    If CanMoveAfterBuilding(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) And CanAttackAfterBuilding(E) Then
                        If Objektverwalter.HatEinheitWaffen(Einheit) = True Then
                            Dim Kosten As Integer = ObjektLadeklasse.GetEinheitenkosten(Einheit)
                            If Kosten >= BilligsterPanzer Then
                                Bauliste.Push(E)
                            ElseIf Einheiten.Length > 20 Then
                                'wenn wir viele Truppen haben bauen wir alles.
                                Bauliste.Push(E)
                            End If
                        ElseIf Einheit = MovementSorts.HOELLIUM.tostring.toupper And Einheiten.Length > 15 And Zufallszahl(0, 20) = 0 Then
                            Bauliste.Push(E)
                        End If
                    End If
                End If
            Next
        Else
            For Each Einheit In BauGebaeude.GetBaulisteThisPlayer
                If BauGebaeude.CanBuildUnit(Einheit) Then
                    If Objektverwalter.HatEinheitWaffen(Einheit) = True Then
                        Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Einheit, Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, )
                        If CanMoveAfterBuilding(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) Then
                            Dim Kosten As Integer = ObjektLadeklasse.GetEinheitenkosten(Einheit)
                            If Kosten >= BilligsterPanzer And Kosten <= TeuersterPanzer Then
                                Bauliste.Push(E)
                            End If
                        End If
                    End If
                End If
            Next
        End If
        If Bauliste.Count > 0 Then
            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, Bauliste(Zufallszahl(0, Bauliste.Count - 1)), 4)
        End If
    End Sub
    ''' <summary>
    ''' Laesst diese KI nach einem gewissen System einen Panzer bzw. Flugzeug bauen.
    ''' </summary>
    ''' <param name="BauGebaeude"></param>
    ''' <remarks></remarks>
    Private Sub CreatePanzerFlugzeuge(ByVal BauGebaeude As ObjektGebaeude, ByVal Prueffonds As Integer)
        Dim Bauliste As New Stack(Of ObjektEinheit)
        If Spieler.Fonds > AllesBauSumme Then
            For Each Einheit In BauGebaeude.GetBaulisteThisPlayer
                If BauGebaeude.CanBuildUnit(Einheit, Prueffonds) Then
                    Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Einheit, Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, )
                    If CanMoveAfterBuilding(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) And CanAttackAfterBuilding(E) Then
                        If Objektverwalter.HatEinheitWaffen(Einheit) = True Then
                            Dim Kosten As Integer = ObjektLadeklasse.GetEinheitenkosten(Einheit)
                            If Kosten >= BilligsterPanzer Then
                                Bauliste.Push(E)
                            ElseIf Einheiten.Length > 20 Then
                                'wenn wir viele Truppen haben bauen wir alles.
                                Bauliste.Push(E)
                            End If
                        ElseIf Einheit = MovementSorts.HOELLIUM.tostring.toupper And Einheiten.Length > 15 And Zufallszahl(0, 20) = 0 Then
                            Bauliste.Push(E)
                        End If
                    End If
                End If
            Next
        Else
            For Each Einheit In BauGebaeude.GetBaulisteThisPlayer
                If BauGebaeude.CanBuildUnit(Einheit, Prueffonds) Then
                    If Objektverwalter.HatEinheitWaffen(Einheit) = True Then
                        Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Einheit, Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, )
                        If CanMoveAfterBuilding(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) Then
                            Dim Kosten As Integer = ObjektLadeklasse.GetEinheitenkosten(Einheit)
                            If Kosten >= BilligsterPanzer And Kosten <= TeuersterPanzer Then
                                Bauliste.Push(E)
                            End If
                        End If
                    End If
                End If
            Next
        End If
        If Bauliste.Count > 0 Then
            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, Bauliste(Zufallszahl(0, Bauliste.Count - 1)), 4)
        End If
    End Sub
    ''' <summary>
    ''' Baut die teuerste Einheit dieses Gebaeudes
    ''' </summary>
    ''' <param name="BauGebaeude"></param>
    ''' <remarks></remarks>
    Private Sub CreateTeursteEinheit(ByVal BauGebaeude As ObjektGebaeude)
        Dim TeuersteEinheit As ObjektEinheit = Nothing
        Dim Preis As Integer = 0
        For Each Einheit In BauGebaeude.GetBaulisteThisPlayer
            If BauGebaeude.CanBuildUnit(Einheit) Then
                Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Einheit, Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, )
                Dim NeuerPreis As Integer = E.Kosten * Spieler.Teurungsrate(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y)
                If CanMoveAfterBuilding(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) And CanAttackAfterBuilding(E) Then
                    If NeuerPreis > Preis Then
                        TeuersteEinheit = E
                        Preis = NeuerPreis
                    ElseIf NeuerPreis = Preis And Zufallszahl(0, 1) = 0 Then
                        TeuersteEinheit = E
                        Preis = NeuerPreis
                    End If
                End If
            End If
        Next
        If Not TeuersteEinheit Is Nothing Then
            GebaeudeAuswaehlen(KIModiExtern.EinheitBauen, BauGebaeude, TeuersteEinheit, 4)
        End If
    End Sub
    ''' <summary>
    ''' Berechnet was die teuerste Einheit dieses Gebaeudes ist.
    ''' </summary>
    ''' <param name="BauGebaeude"></param>
    ''' <param name="Fonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetTeuersteEinheitenPreis(ByVal BauGebaeude As ObjektGebaeude, ByVal Fonds As Integer) As Integer
        Dim Preis As Integer = -1
        For Each Einheit In BauGebaeude.GetBaulisteThisPlayer
            If BauGebaeude.CanBuildUnit(Einheit, Fonds) Then
                Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Einheit, Spieler.Spieler, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y, )
                Dim NeuerPreis As Integer = E.Kosten * Spieler.Teurungsrate(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y)
                If CanMoveAfterBuilding(E, BauGebaeude.Rechteck.X, BauGebaeude.Rechteck.Y) And CanAttackAfterBuilding(E) Then
                    If NeuerPreis > Preis Then
                        Preis = NeuerPreis
                    ElseIf NeuerPreis = Preis And Zufallszahl(0, 1) = 0 Then
                        Preis = NeuerPreis
                    End If
                End If
            End If
        Next
        Return Preis
    End Function
#End Region
    ''' <summary>
    ''' Mit dieser Funktion beenden die einfachen KI's die Runde
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub RundenEnde()
        If Spieler.KOS(0).Gabemodus = ObjektKO.Gabemodi.Keine Then
            Dim GabefuellstandKO1 As Integer = Spieler.KOS(0).Gabeleiste
            Dim GabefuellstandKO2 As Integer = -1
            If IsNothing(Spieler.KOS(1)) = False Then
                GabefuellstandKO2 = Spieler.KOS(1).Gabeleiste
            End If
            If GabefuellstandKO2 >= 0 Then
                If Objektverwalter.Spielfeld.Regeln.DoppelGabe Then
                    GabefuellstandKO1 = ((Spieler.KOS(0).SpezialgabeKosten + Spieler.KOS(0).Gabekosten) * Spieler.KOS(0).Sternkosten - GabefuellstandKO1)
                    GabefuellstandKO2 = ((Spieler.KOS(1).SpezialgabeKosten + Spieler.KOS(1).Gabekosten) * Spieler.KOS(1).Sternkosten - GabefuellstandKO2)
                    If GabefuellstandKO1 < 1500 And GabefuellstandKO2 < 1500 Then
                        If Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.Beides Then
                            RundenEndeMitWechsel = True
                            Spieler.Wechsel()
                        ElseIf Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenAnfang Then
                            RundenEndeMitWechsel = True
                            Spieler.Wechsel()
                        End If
                    ElseIf GabefuellstandKO1 - GabefuellstandKO2 < -1000 Then
                        RundenEndeMitWechsel = True
                        Spieler.Wechsel()
                    End If
                Else
                    Dim Dif1 As Integer = ((Spieler.KOS(0).SpezialgabeKosten + Spieler.KOS(0).Gabekosten) * Spieler.KOS(0).Sternkosten - GabefuellstandKO1)
                    Dim Dif2 As Integer = ((Spieler.KOS(1).SpezialgabeKosten + Spieler.KOS(1).Gabekosten) * Spieler.KOS(1).Sternkosten - GabefuellstandKO2)
                    If Dif1 > Dif2 Then
                        RundenEndeMitWechsel = True
                        Spieler.Wechsel()
                    End If
                End If
            End If
        ElseIf Spieler.KOS(0).Gabemodus = ObjektKO.Gabemodi.Doppelgabe Then
            If Spieler.KOS(1).Gabemodus = ObjektKO.Gabemodi.Keine Then
                RundenEndeMitWechsel = True
                Spieler.Wechsel()
            End If
        End If
        Schleife = True
    End Sub

#Region "Fernkampf"
    Function GetBestesFernkampfOpferMitBewegung(ByVal Einheit As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point2
        Dim Opfer() As Point2 = GetAllFernkampfFeldermitBewegungNormal(Einheit, WSS)
        If Opfer.Length > 0 Then
            Dim MomentanesOpfer As Integer = 0
            Dim MomentanerSchaden As Integer = 0
            Dim Fernwaffe As Boolean = False
            For I = 0 To Opfer.Length - 1
                Dim UnserOpfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld)
                If UnserOpfer IsNot Nothing Then
                    Dim Glueck As Point = Spieler.GetGlueckPech(Opfer(I).Point1.X, Opfer(I).Point1.Y)
                    If Gluecksfaktor > 0 Then
                        Glueck.X *= Gluecksfaktor
                    Else
                        Glueck.X = Glueck.Y * Gluecksfaktor
                    End If
                    Dim OpferLeben As Single = UnserOpfer.Leben
                    Dim Schaden As Integer = UnserOpfer.Kosten * Objektverwalter.Spielfeld.Spieler(UnserOpfer.Spieler).Teurungsrate(UnserOpfer, UnserOpfer.X, UnserOpfer.Y) * Objektverwalter.Schadensberechnung(Einheit, Einheit.X, Einheit.Y, UnserOpfer.X, UnserOpfer.Y, Einheit.Leben, OpferLeben, False, True, Glueck.X, UnserOpfer, False)(0)
                    If Fernwaffe = False Then
                        If UnserOpfer.MaximaleReichweite > 1 Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                            Fernwaffe = True
                        Else
                            If Schaden > MomentanerSchaden Then
                                MomentanerSchaden = Schaden
                                MomentanesOpfer = I
                            ElseIf Schaden = MomentanerSchaden And Zufallszahl(0, 1) = 1 Then
                                MomentanerSchaden = Schaden
                                MomentanesOpfer = I
                            End If
                        End If
                    ElseIf UnserOpfer.MaximaleReichweite > 1 Then
                        If Schaden > MomentanerSchaden Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        ElseIf Schaden = MomentanerSchaden And Zufallszahl(0, 1) = 1 Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        End If
                    End If
                Else
                    'Wir greifen ein Gebaeude oder eine Landschaft an.
                    If Objektverwalter.Spielfeld.Landschaften(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld).Leben > 0 Then
                        If MomentanerSchaden = 0 Then
                            If MomentanesOpfer <> 0 Then
                                If Zufallszahl(0, 1) = 0 Then
                                    MomentanesOpfer = I
                                End If
                            Else
                                MomentanesOpfer = I
                            End If
                        End If
                    Else
                        Dim G As ObjektGebaeude = Objektverwalter.Spielfeld.Landschaften(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld).Gebaeude
                        Dim Schaden As Integer = ObjektLadeklasse.GetGebaeudeKosten(G.GebaeudeID, G.Spieler) / G.GetMaxLeben * Tabellenverwalter.GetWert(Einheit.Waffe2, "Gebaeude")
                        If Schaden > MomentanerSchaden Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        ElseIf Schaden = MomentanerSchaden And Zufallszahl(0, 1) = 1 Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        End If
                    End If
                End If
            Next
            Return Opfer(MomentanesOpfer)
        Else
            Return New Point2(New Point(-1, -1), New Point(-1, -1))
        End If
    End Function
    Function GetAllFernkampfFeldermitBewegungNormal(ByVal Einheit As ObjektEinheit, Optional ByRef WSS As Wegsuchsystem = Nothing) As Point2()
        Dim Felder As New Stack(Of Point2)
        If Einheit.MaximaleReichweite > 1 Then
            Dim Bewegunspunkte As Integer = Einheit.GetMovementRange
            If WSS Is Nothing Then
                If Bewegunspunkte <= Einheit.Treibstoff Then
                    WSS = New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, Bewegunspunkte)
                ElseIf Einheit.Treibstoff = -1 Then
                    WSS = New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, Bewegunspunkte)
                Else
                    WSS = New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, Einheit.Treibstoff)
                End If
            End If
            For Y1 = 0 To Objektverwalter.Spielfeld.Hoehe - 1
                For X1 = 0 To Objektverwalter.Spielfeld.Breite - 1
                    Dim Kosten As Integer = WSS.getBewegungspunktekosten(X1, Y1)
                    Dim neuerPunkt As Point = New Point(X1, Y1)
                    If Kosten >= 0 And Kosten <= Bewegunspunkte Then
                        If Objektverwalter.Spielfeld.OnMap(neuerPunkt.X, neuerPunkt.Y) Then
                            If IsFeldLeer(neuerPunkt.X, neuerPunkt.Y, Einheit) = True Then
                                If IsFernZielFuerEinheit(Einheit, neuerPunkt.X, neuerPunkt.Y) = False Then
                                    'So dieses Feld kann betreten werden und jetzt schiessen wir von ihm aus.
                                    Dim Felder2 As Point() = GetAllFernKampfFelderGebaeude(Einheit, neuerPunkt.X, neuerPunkt.Y, True)
                                    For Each Feld In Felder2
                                        Felder.Push(New Point2(neuerPunkt, Feld))
                                    Next
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        End If
        Return Felder.ToArray
    End Function
    Function GetNaehestesFernkampffeldSicher(ByVal Einheit As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point
        Dim Ziel As New Point(-1, -1)
        Dim MomentaneWegkosten As Integer = -1
        If Einheit.MaximaleReichweite > 1 Then
            If WSS Is Nothing Then
                WSS = New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, -1)
            End If
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Hoehe
                    If WSS.getBewegungspunktekosten(X, Y) >= 0 Then
                        If IsFeldLeer(X, Y, Einheit) = True Then
                            If IsFernZielFuerEinheit(Einheit, X, Y) = False Or WSS.getRundeDiskret(WSS.getBewegungspunktekosten(X, Y), False) > 0 Then
                                If IsBeschussFeldVon(X, Y, BeschussArten.Geschuetzfeind) = False Then
                                    'Wir koennen das Feld erreichen
                                    If KannFernkampfGemachtWerden(Einheit, X, Y) = True Then
                                        If WSS.getBewegungspunktekosten(X, Y) < MomentaneWegkosten Then
                                            MomentaneWegkosten = WSS.getBewegungspunktekosten(X, Y)
                                            Ziel = New Point(X, Y)
                                        ElseIf WSS.getBewegungspunktekosten(X, Y) = MomentaneWegkosten And Zufallszahl(0, 1) = 1 Then
                                            MomentaneWegkosten = WSS.getBewegungspunktekosten(X, Y)
                                            Ziel = New Point(X, Y)
                                        ElseIf MomentaneWegkosten = -1 Then
                                            MomentaneWegkosten = WSS.getBewegungspunktekosten(X, Y)
                                            Ziel = New Point(X, Y)
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        End If
        Return Ziel
    End Function
#End Region
#Region "Nahkampf"
    ''' <summary>
    ''' Gibt das beste Opfer dieser Einheit von der momentanen Position zurueck.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns>Gibt (-1,-1) zurueck wenn kein Opfer gefunden</returns>
    ''' <remarks></remarks>
    Function GetBestesNahkampfOpferFeldSicher(ByVal Einheit As ObjektEinheit, ByRef WSS As Wegsuchsystem, ByVal Opfer() As Point2) As Point2
        If Opfer.Length > 0 Then
            Dim MomentanesOpfer As Integer = -1
            Dim MomentanerSchaden As Single = 0
            Dim MomentaneTPDifferenz As Single = -100
            Dim Deckung As Integer = 0
            Dim Fernwaffen As Integer = False
            For I = 0 To Opfer.Length - 1
                Dim UnserOpfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld)
                'Wir berechnen wie viel Geldschaden wir anrichten wuerden
                Dim TPDifferenz As Single = 0
                Dim Schaden As Single = GetGeldschaden(Einheit, Opfer(I).Point1.X, Opfer(I).Point1.Y, UnserOpfer, TPDifferenz)
                Dim DeckungMom As Integer = Spieler.GetDeffensivSterne(UnserOpfer, Objektverwalter.Spielfeld.Landschaften(Opfer(I).Point1.X, Opfer(I).Point1.Y, Schlachtfeld))
                If IsFernZielFuerEinheit(Einheit, Opfer(I).Point1.X, Opfer(I).Point1.Y) Then
                    Schaden = -1
                End If
                If Schaden >= MinimalerGeldschaden Then
                    If Schaden > MomentanerSchaden Then
                        MomentanerSchaden = Schaden
                        MomentanesOpfer = I
                        Deckung = DeckungMom
                    ElseIf Schaden = MomentanerSchaden And DeckungMom > Deckung Then
                        MomentanerSchaden = Schaden
                        MomentanesOpfer = I
                        Deckung = DeckungMom
                    ElseIf Schaden = MomentanerSchaden And DeckungMom = Deckung And Zufallszahl(0, 1) = 0 Then
                        MomentanerSchaden = Schaden
                        MomentanesOpfer = I
                        Deckung = DeckungMom
                    End If
                ElseIf TPDifferenz >= MinimaleTPDifferenz Then
                    If TPDifferenz > MinimaleTPDifferenz Then
                        If TPDifferenz > MomentaneTPDifferenz Then
                            MomentaneTPDifferenz = TPDifferenz
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf TPDifferenz = MomentaneTPDifferenz And DeckungMom > Deckung Then
                            MomentaneTPDifferenz = TPDifferenz
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf TPDifferenz = MomentaneTPDifferenz And DeckungMom = Deckung And Zufallszahl(0, 1) = 0 Then
                            MomentaneTPDifferenz = TPDifferenz
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        End If
                    End If
                End If
            Next
            If MomentanesOpfer < 0 Then
                Return New Point2(New Point(-1, -1), New Point(-1, -1))
            Else
                Return Opfer(MomentanesOpfer)
            End If
        Else
            Return New Point2(New Point(-1, -1), New Point(-1, -1))
        End If
    End Function
    Protected Overrides Function CalculateRealZiel(ByRef WSS As Wegsuchsystem, ByVal Ziel As Point, ByVal Einheit As ObjektEinheit, ByRef Opfer As Point) As Point
        Dim Z As Point = Ziel

        Return Z
    End Function
#End Region
#Region "Ration"
    Private Function GetNaehestesRationsFeld(ByVal Einheit As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point
        Dim Ziel As Point = New Point(-1, -1)
        Dim MinBew As Integer = -1
        For X = 0 To Objektverwalter.Spielfeld.Breite - 1
            For Y = 0 To Objektverwalter.Spielfeld.Hoehe - 1
                Dim BewPunkte As Integer = WSS.getBewegungspunktekosten(X, Y)
                If BewPunkte >= 0 Then
                    If Not IsBeschussFeldVon(X, Y, BeschussArten.HeilungEigene) Then
                        If Einheit.getKP < MinimaleKP Then
                            'Jetzt wird es schwerer.
                            Dim G As ObjektGebaeude = Objektverwalter.Spielfeld.Landschaften(X, Y, Schlachtfeld).Gebaeude
                            If Not G Is Nothing Then
                                If G.Spieler = Spieler.Spieler Then
                                    If IsFeldLeer(X, Y, Einheit) Then
                                        Dim BList() As String = G.GetBaulisteThisPlayer
                                        If BList.Length > 0 Then
                                            If BList.Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        ElseIf G.Versorung Then
                                            If ObjektLadeklasse.GetBauliste("BASIS").Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        ElseIf RationsEinheitNebenAn(X, Y, Einheit) Then
                            If IsFeldLeer(X, Y, Einheit) Then
                                If BewPunkte < MinBew Or MinBew < 0 Then
                                    MinBew = BewPunkte
                                    Ziel = New Point(X, Y)
                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                    MinBew = BewPunkte
                                    Ziel = New Point(X, Y)
                                End If
                            End If
                        Else
                            Dim G As ObjektGebaeude = Objektverwalter.Spielfeld.Landschaften(X, Y, Schlachtfeld).Gebaeude
                            If Not G Is Nothing Then
                                If G.Spieler = Spieler.Spieler Then
                                    If IsFeldLeer(X, Y, Einheit) Then
                                        Dim BList As String() = G.GetBaulisteThisPlayer
                                        If BList.Length > 0 Then
                                            If BList.Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        ElseIf G.Versorung Then
                                            If ObjektLadeklasse.GetBauliste("BASIS").Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    Else
                        If BewPunkte < MinBew Or MinBew < 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        End If
                    End If
                End If
            Next
        Next
        Return Ziel
    End Function
    ''' <summary>
    ''' Gibt zurueck ob neben an eine Einheit ist die Ration verteilen kann.
    ''' </summary>
    ''' <param name="X"></param>
    ''' <param name="Y"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function RationsEinheitNebenAn(ByVal X As Integer, ByVal Y As Integer, ByVal Einheit As ObjektEinheit) As Boolean
        Dim X2 As Integer = X
        Dim Y2 As Integer = Y
        For I = 0 To 3
            Select Case I
                Case 0
                    X2 -= 1
                Case 1
                    X2 += 1
                    Y2 -= 1
                Case 2
                    X2 += 1
                    Y2 += 1
                Case 3
                    X2 -= 1
                    Y2 += 1
            End Select
            If Objektverwalter.Spielfeld.OnMap(X2, Y2) Then
                Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X2, Y2, Schlachtfeld)
                If Not E Is Nothing Then
                    If E.Spieler = Spieler.Spieler Then
                        If E.Faehigkeit = "Ration" Then
                            If Not E.Equals(Einheit) Then
                                Return True
                            End If
                        ElseIf E.Faehigkeit = "RationSame" Then
                            If E.IsGroundUnit = Einheit.IsGroundUnit Or _
                                        E.IsFlyingUnit = Einheit.IsFlyingUnit Or _
                                        E.IsSeaUnit = Einheit.IsSeaUnit Then
                                Return True
                            End If
                        End If
                    End If
                End If
            End If
        Next
        Return False
    End Function
    Private Function GetNaehestesRationsVerteilFeld(ByVal E As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point
        Dim Ziel As Point = New Point(-1, -1)
        Dim MinBew As Integer = -1
        For X = 0 To Objektverwalter.Spielfeld.Breite - 1
            For Y = 0 To Objektverwalter.Spielfeld.Hoehe - 1
                Dim BewPunkte As Integer = WSS.getBewegungspunktekosten(X, Y)
                If BewPunkte >= 0 Then
                    If IsVersorgungsEinheitNebenAn(X, Y, E) Then
                        If BewPunkte < MinBew Or MinBew < 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        End If
                    End If
                End If
            Next
        Next
        Return Ziel
    End Function
    Private Function IsVersorgungsEinheitNebenAn(ByVal X As Integer, ByVal Y As Integer, ByVal E2 As ObjektEinheit) As Boolean
        Dim X2 As Integer = X
        Dim Y2 As Integer = Y
        For I = 0 To 3
            Select Case I
                Case 0
                    X2 -= 1
                Case 1
                    X2 += 1
                    Y2 -= 1
                Case 2
                    X2 += 1
                    Y2 += 1
                Case 3
                    X2 -= 1
                    Y2 += 1
            End Select
            If Objektverwalter.Spielfeld.OnMap(X2, Y2) Then
                Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X2, Y2, Schlachtfeld)
                If Not E Is Nothing Then
                    If E.Spieler = Spieler.Spieler Then
                        If E.IsLowPowerUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) Then
                            If E.getKP >= MinimaleKP Then
                                If E2.Faehigkeit = "RationSame" Then
                                    If E.IsGroundUnit = E2.IsGroundUnit Or _
                                        E.IsFlyingUnit = E2.IsFlyingUnit Or _
                                        E.IsSeaUnit = E2.IsSeaUnit Then
                                        Return True
                                    End If
                                Else
                                    Return True
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        Next
        Return False
    End Function
#End Region
End Class
